Introduction

Aiming to show a complete workthrough of 10X Spatial Gene Expression data from raw reads to analysis and visualization using 10X genomics spaceranger and Seurat.

Acknowledgements

Tutorial adapted from 10X spaceranger tutorial and Seurat vignette

Data

The data is publicly available Mouse Kidney Section

https://www.10xgenomics.com/resources/datasets/mouse-kidney-section-coronal-1-standard-1-1-0

curl https://s3-us-west-2.amazonaws.com/10x.files/samples/spatial-exp/1.1.0/datasets/V1_Mouse_Kidney_fastqs.tar
 -o V1_Mouse_Kidney/V1_V1_Mouse_Kidney_fastqs.tar
curl https://cf.10xgenomics.com/samples/spatial-exp/1.1.0/datasets/V1_Mouse_Kidney_image.tif -o V1_Mouse_Kidney/V1_Adult_V1_Mouse_Kidney_image.tif

tar -xvf datasets/V1_Mouse_Kidney_fastqs.tar

# Download mouse reference
curl -O https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-mm10-2020-A.tar.gz

Space ranger was used with the following params:

./spaceranger-2.0.0/spaceranger count --id="V1_Adult_Mouse_kidney" \
                   --description="Adult Mouse kidney (Coronal)" \
                   --transcriptome=refdata-gex-mm10-2020-A \
                   --fastqs=datasets/V1_Adult_Mouse_kidney_fastqs \
                   --image=datasets/V1_Adult_V1_Mouse_Kidney_image.tif \
                   --slide=V19L01-041 \
                   --area=C1 \
                       --jobmode=local \
                   --localcores=8 \
                       --localmem=40

Load libraries

library(Seurat)
library(ggplot2)
library(patchwork)
library(dplyr)

We are loading in the data directly from the output of spaceranger

Make sure hd5f libraries are installed

#kidney <- 
kidney <- Load10X_Spatial(data.dir ="../Mouse-Kidney-section/outs/")
kidney
An object of class Seurat 
32285 features across 1443 samples within 1 assay 
Active assay: Spatial (32285 features, 0 variable features)
 1 image present: slice1

Data preprocessing

plot1 <- VlnPlot(kidney, features = "nCount_Spatial", pt.size = 0.1) + NoLegend()
plot2 <- SpatialFeaturePlot(kidney, features = "nCount_Spatial") + theme(legend.position = "right")
wrap_plots(plot1, plot2)

The plots show quite a wide variance in molecular counts. This is due to technical variation but also due to natural variation in tissue types across the section. For this reason LogNormalise() is not suitable and Seurat reccomend rthe use of SCTransform() instead

kidney <- SCTransform(kidney, assay = "Spatial", verbose = FALSE)

Visualisation

Highlight particular features

SpatialFeaturePlot(kidney, features = c("Hpca", "Ttr"))

Dimensionality reduction, clustering, and visualization

kidney <- RunPCA(kidney, assay = "SCT", verbose = FALSE)
kidney <- FindNeighbors(kidney, reduction = "pca", dims = 1:30)
kidney <- FindClusters(kidney, verbose = FALSE)
kidney <- RunUMAP(kidney, reduction = "pca", dims = 1:30)
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
p1 <- DimPlot(kidney, reduction = "umap", label = TRUE)
p2 <- SpatialDimPlot(kidney, label = TRUE, label.size = 3)
p1 + p2

SpatialDimPlot(kidney, cells.highlight = CellsByIdentities(object = kidney, idents = c(0:10)), facet.highlight = TRUE, ncol = 5)

Interactive plots

SpatialDimPlot(kidney, interactive = TRUE) 

SpatialFeaturePlot(kidney, features = "Ttr", interactive = TRUE)

Identification of spatially variable features

1st method : Using prior knowledge

de_markers <- FindMarkers(kidney, ident.1 = 5, ident.2 = 6)

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~13s          
  |++                                                | 2 % ~14s          
  |++                                                | 3 % ~12s          
  |+++                                               | 4 % ~11s          
  |+++                                               | 5 % ~10s          
  |++++                                              | 6 % ~09s          
  |++++                                              | 7 % ~08s          
  |+++++                                             | 8 % ~09s          
  |+++++                                             | 9 % ~08s          
  |++++++                                            | 10% ~08s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 12% ~07s          
  |+++++++                                           | 13% ~07s          
  |++++++++                                          | 14% ~08s          
  |++++++++                                          | 15% ~07s          
  |+++++++++                                         | 16% ~07s          
  |+++++++++                                         | 17% ~07s          
  |++++++++++                                        | 18% ~07s          
  |++++++++++                                        | 19% ~07s          
  |+++++++++++                                       | 20% ~07s          
  |+++++++++++                                       | 21% ~07s          
  |++++++++++++                                      | 22% ~06s          
  |++++++++++++                                      | 23% ~06s          
  |+++++++++++++                                     | 24% ~06s          
  |+++++++++++++                                     | 25% ~06s          
  |++++++++++++++                                    | 26% ~06s          
  |++++++++++++++                                    | 27% ~06s          
  |+++++++++++++++                                   | 28% ~06s          
  |+++++++++++++++                                   | 29% ~06s          
  |++++++++++++++++                                  | 30% ~06s          
  |++++++++++++++++                                  | 31% ~05s          
  |+++++++++++++++++                                 | 32% ~05s          
  |+++++++++++++++++                                 | 33% ~05s          
  |++++++++++++++++++                                | 34% ~05s          
  |++++++++++++++++++                                | 35% ~05s          
  |+++++++++++++++++++                               | 36% ~05s          
  |+++++++++++++++++++                               | 37% ~05s          
  |++++++++++++++++++++                              | 38% ~05s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~04s          
  |++++++++++++++++++++++                            | 42% ~04s          
  |++++++++++++++++++++++                            | 43% ~04s          
  |+++++++++++++++++++++++                           | 44% ~04s          
  |+++++++++++++++++++++++                           | 45% ~04s          
  |++++++++++++++++++++++++                          | 46% ~04s          
  |++++++++++++++++++++++++                          | 47% ~04s          
  |+++++++++++++++++++++++++                         | 48% ~04s          
  |+++++++++++++++++++++++++                         | 49% ~04s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |+++++++++++++++++++++++++++                       | 54% ~03s          
  |++++++++++++++++++++++++++++                      | 55% ~03s          
  |++++++++++++++++++++++++++++                      | 56% ~03s          
  |+++++++++++++++++++++++++++++                     | 57% ~03s          
  |+++++++++++++++++++++++++++++                     | 58% ~03s          
  |++++++++++++++++++++++++++++++                    | 59% ~03s          
  |++++++++++++++++++++++++++++++                    | 60% ~03s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |+++++++++++++++++++++++++++++++                   | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |++++++++++++++++++++++++++++++++                  | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~02s          
  |++++++++++++++++++++++++++++++++++                | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=07s  
SpatialFeaturePlot(object = kidney, features = rownames(de_markers)[1:3], alpha = c(0.1, 1), ncol = 3)

2nd method: Looking for patterns in the data

kidney <- FindSpatiallyVariableFeatures(kidney, assay = "SCT", features = VariableFeatures(kidney)[1:500],
    selection.method = "markvariogram")

More tutorials on data integration, subsetting and multiple slice data available at https://satijalab.org/seurat/articles/spatial_vignette.html

sessionInfo()
LS0tCnRpdGxlOiAiU3BhdGlhbCB0cmFuc2NyaXB0b21pY3MgaW4gc3BhY2VyYW5nZXIgYW5kIFNldXJhdCB3b3JrZmxvdyIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogIkVtaWx5IENoYW1iZXJzIgpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIHRpZHkgPSBUUlVFLAogIHRpZHkub3B0cyA9IGxpc3Qod2lkdGguY3V0b2ZmID0gOTUpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgZmlnLndpZHRoID0gMTAsCiAgdGltZV9pdCA9IFRSVUUKKQoKYGBgCiMgSW50cm9kdWN0aW9uCgpBaW1pbmcgdG8gc2hvdyBhIGNvbXBsZXRlIHdvcmt0aHJvdWdoIG9mIDEwWCBTcGF0aWFsIEdlbmUgRXhwcmVzc2lvbiBkYXRhIGZyb20gcmF3IHJlYWRzIHRvIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uIHVzaW5nIDEwWCBnZW5vbWljcyBzcGFjZXJhbmdlciBhbmQgU2V1cmF0LgoKIyBBY2tub3dsZWRnZW1lbnRzCgpUdXRvcmlhbCBhZGFwdGVkIGZyb20gMTBYIHNwYWNlcmFuZ2VyIHR1dG9yaWFsIGFuZCBTZXVyYXQgdmlnbmV0dGUKCi0gICA8aHR0cHM6Ly9naXRodWIuY29tL3NhdGlqYWxhYi9zZXVyYXQvYmxvYi9tYXN0ZXIvdmlnbmV0dGVzL3NwYXRpYWxfdmlnbmV0dGUuUm1kPgotICAgPGh0dHBzOi8vc3VwcG9ydC4xMHhnZW5vbWljcy5jb20vc3BhdGlhbC1nZW5lLWV4cHJlc3Npb24vc29mdHdhcmUvcGlwZWxpbmVzL2xhdGVzdC90dXRvcmlhbHMvY291bnQtZmYtdHV0b3JpYWw+CgojIERhdGEKClRoZSBkYXRhIGlzIHB1YmxpY2x5IGF2YWlsYWJsZSBNb3VzZSBLaWRuZXkgU2VjdGlvbgoKLSAgIFNlcXVlbmNpbmcgRGVwdGg6IDI2MSwxMjIgcmVhZCBwYWlycyBwZXIgc3BvdAotICAgU2VxdWVuY2luZyBDb25maWd1cmF0aW9uOiAyOCB4IDEyMCBicAotICAgU2VxdWVuY2luZyBDb3ZlcmFnZTogUmVhZCAxIC0gMjggYnAgKGluY2x1ZGVzIDE2IGJwIFNwYXRpYWwgQmFyY29kZSwgMTIgYnAgVU1JKTsgUmVhZCAyIC0gMTIwIGJwICh0cmFuc2NyaXB0KTsgaTcgc2FtcGxlIGluZGV4IC0gMTAgYnA7IGk1IHNhbXBsZSBpbmRleCAtIDEwIGJwLgotICAgU2xpZGU6IFYxOUwyOS0wOTYKLSAgIEFyZWE6IEIxCgo8aHR0cHM6Ly93d3cuMTB4Z2Vub21pY3MuY29tL3Jlc291cmNlcy9kYXRhc2V0cy9tb3VzZS1raWRuZXktc2VjdGlvbi1jb3JvbmFsLTEtc3RhbmRhcmQtMS0xLTA+CgpgYGB7YmFzaCwgZXZhbCAgPUZBTFNFfQpjdXJsIGh0dHBzOi8vczMtdXMtd2VzdC0yLmFtYXpvbmF3cy5jb20vMTB4LmZpbGVzL3NhbXBsZXMvc3BhdGlhbC1leHAvMS4xLjAvZGF0YXNldHMvVjFfTW91c2VfS2lkbmV5X2Zhc3Rxcy50YXIKIC1vIFYxX01vdXNlX0tpZG5leS9WMV9WMV9Nb3VzZV9LaWRuZXlfZmFzdHFzLnRhcgpjdXJsIGh0dHBzOi8vY2YuMTB4Z2Vub21pY3MuY29tL3NhbXBsZXMvc3BhdGlhbC1leHAvMS4xLjAvZGF0YXNldHMvVjFfTW91c2VfS2lkbmV5X2ltYWdlLnRpZiAtbyBWMV9Nb3VzZV9LaWRuZXkvVjFfQWR1bHRfVjFfTW91c2VfS2lkbmV5X2ltYWdlLnRpZgoKdGFyIC14dmYgZGF0YXNldHMvVjFfTW91c2VfS2lkbmV5X2Zhc3Rxcy50YXIKCiMgRG93bmxvYWQgbW91c2UgcmVmZXJlbmNlCmN1cmwgLU8gaHR0cHM6Ly9jZi4xMHhnZW5vbWljcy5jb20vc3VwcC9zcGF0aWFsLWV4cC9yZWZkYXRhLWdleC1tbTEwLTIwMjAtQS50YXIuZ3oKCmBgYAoKU3BhY2UgcmFuZ2VyIHdhcyB1c2VkIHdpdGggdGhlIGZvbGxvd2luZyBwYXJhbXM6CgpgYGB7YmFzaCwgZXZhbCAgPUZBTFNFfQouL3NwYWNlcmFuZ2VyLTIuMC4wL3NwYWNlcmFuZ2VyIGNvdW50IC0taWQ9IlYxX0FkdWx0X01vdXNlX2tpZG5leSIgXAogICAgICAgICAgICAgICAgICAgLS1kZXNjcmlwdGlvbj0iQWR1bHQgTW91c2Uga2lkbmV5IChDb3JvbmFsKSIgXAogICAgICAgICAgICAgICAgICAgLS10cmFuc2NyaXB0b21lPXJlZmRhdGEtZ2V4LW1tMTAtMjAyMC1BIFwKICAgICAgICAgICAgICAgICAgIC0tZmFzdHFzPWRhdGFzZXRzL1YxX0FkdWx0X01vdXNlX2tpZG5leV9mYXN0cXMgXAogICAgICAgICAgICAgICAgICAgLS1pbWFnZT1kYXRhc2V0cy9WMV9BZHVsdF9WMV9Nb3VzZV9LaWRuZXlfaW1hZ2UudGlmIFwKICAgICAgICAgICAgICAgICAgIC0tc2xpZGU9VjE5TDAxLTA0MSBcCiAgICAgICAgICAgICAgICAgICAtLWFyZWE9QzEgXAoJCSAgICAgICAgICAgICAgIC0tam9ibW9kZT1sb2NhbCBcCiAgICAgICAgICAgICAgICAgICAtLWxvY2FsY29yZXM9OCBcCgkJICAgICAgICAgICAgICAgLS1sb2NhbG1lbT00MAoJCSAgICAgICAgICAgICAgIApgYGAKCiMgTG9hZCBsaWJyYXJpZXMKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShkcGx5cikKYGBgCgpXZSBhcmUgbG9hZGluZyBpbiB0aGUgZGF0YSBkaXJlY3RseSBmcm9tIHRoZSBvdXRwdXQgb2Ygc3BhY2VyYW5nZXIKCk1ha2Ugc3VyZSBoZDVmIGxpYnJhcmllcyBhcmUgaW5zdGFsbGVkCgpgYGB7cn0KI2tpZG5leSA8LSAKa2lkbmV5IDwtIExvYWQxMFhfU3BhdGlhbChkYXRhLmRpciA9Ii4uL01vdXNlLUtpZG5leS1zZWN0aW9uL291dHMvIikKa2lkbmV5CgoKYGBgCgojIERhdGEgcHJlcHJvY2Vzc2luZwoKYGBge3J9CnBsb3QxIDwtIFZsblBsb3Qoa2lkbmV5LCBmZWF0dXJlcyA9ICJuQ291bnRfU3BhdGlhbCIsIHB0LnNpemUgPSAwLjEpICsgTm9MZWdlbmQoKQpwbG90MiA8LSBTcGF0aWFsRmVhdHVyZVBsb3Qoa2lkbmV5LCBmZWF0dXJlcyA9ICJuQ291bnRfU3BhdGlhbCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKd3JhcF9wbG90cyhwbG90MSwgcGxvdDIpCgpgYGAKVGhlIHBsb3RzIHNob3cgcXVpdGUgYSB3aWRlIHZhcmlhbmNlIGluIG1vbGVjdWxhciBjb3VudHMuIFRoaXMgaXMgZHVlIHRvIHRlY2huaWNhbCB2YXJpYXRpb24gYnV0IGFsc28gZHVlIHRvIG5hdHVyYWwgdmFyaWF0aW9uIGluIHRpc3N1ZSB0eXBlcyBhY3Jvc3MgdGhlIHNlY3Rpb24uIEZvciB0aGlzIHJlYXNvbiBMb2dOb3JtYWxpc2UoKSBpcyBub3Qgc3VpdGFibGUgYW5kIFNldXJhdCByZWNjb21lbmQgcnRoZSB1c2Ugb2YgU0NUcmFuc2Zvcm0oKSBpbnN0ZWFkCmBgYHtyfQpraWRuZXkgPC0gU0NUcmFuc2Zvcm0oa2lkbmV5LCBhc3NheSA9ICJTcGF0aWFsIiwgdmVyYm9zZSA9IEZBTFNFKQpgYGAKCiMgVmlzdWFsaXNhdGlvbgoKSGlnaGxpZ2h0IHBhcnRpY3VsYXIgZmVhdHVyZXMKYGBge3J9ClNwYXRpYWxGZWF0dXJlUGxvdChraWRuZXksIGZlYXR1cmVzID0gYygiSHBjYSIsICJUdHIiKSkKYGBgCgoKIyBEaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24sIGNsdXN0ZXJpbmcsIGFuZCB2aXN1YWxpemF0aW9uCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpraWRuZXkgPC0gUnVuUENBKGtpZG5leSwgYXNzYXkgPSAiU0NUIiwgdmVyYm9zZSA9IEZBTFNFKQpraWRuZXkgPC0gRmluZE5laWdoYm9ycyhraWRuZXksIHJlZHVjdGlvbiA9ICJwY2EiLCBkaW1zID0gMTozMCkKa2lkbmV5IDwtIEZpbmRDbHVzdGVycyhraWRuZXksIHZlcmJvc2UgPSBGQUxTRSkKa2lkbmV5IDwtIFJ1blVNQVAoa2lkbmV5LCByZWR1Y3Rpb24gPSAicGNhIiwgZGltcyA9IDE6MzApCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CnAxIDwtIERpbVBsb3Qoa2lkbmV5LCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSkKcDIgPC0gU3BhdGlhbERpbVBsb3Qoa2lkbmV5LCBsYWJlbCA9IFRSVUUsIGxhYmVsLnNpemUgPSAzKQpwMSArIHAyCmBgYAoKYGBge3IsIGZpZy53aWR0aD0zMH0KU3BhdGlhbERpbVBsb3Qoa2lkbmV5LCBjZWxscy5oaWdobGlnaHQgPSBDZWxsc0J5SWRlbnRpdGllcyhvYmplY3QgPSBraWRuZXksIGlkZW50cyA9IGMoMDoxMCkpLCBmYWNldC5oaWdobGlnaHQgPSBUUlVFLCBuY29sID0gNSkKYGBgCiMgSW50ZXJhY3RpdmUgcGxvdHMKYGBge3IsIGV2YWw9RkFMU0V9ClNwYXRpYWxEaW1QbG90KGtpZG5leSwgaW50ZXJhY3RpdmUgPSBUUlVFKSAKClNwYXRpYWxGZWF0dXJlUGxvdChraWRuZXksIGZlYXR1cmVzID0gIlR0ciIsIGludGVyYWN0aXZlID0gVFJVRSkKYGBgCgojIElkZW50aWZpY2F0aW9uIG9mIHNwYXRpYWxseSB2YXJpYWJsZSBmZWF0dXJlcwoKMXN0IG1ldGhvZCA6IFVzaW5nIHByaW9yIGtub3dsZWRnZQoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CmRlX21hcmtlcnMgPC0gRmluZE1hcmtlcnMoa2lkbmV5LCBpZGVudC4xID0gNSwgaWRlbnQuMiA9IDYpClNwYXRpYWxGZWF0dXJlUGxvdChvYmplY3QgPSBraWRuZXksIGZlYXR1cmVzID0gcm93bmFtZXMoZGVfbWFya2VycylbMTozXSwgYWxwaGEgPSBjKDAuMSwgMSksIG5jb2wgPSAzKQoKYGBgCgoybmQgbWV0aG9kOiBMb29raW5nIGZvciBwYXR0ZXJucyBpbiB0aGUgZGF0YQoKYGBge3J9CmtpZG5leSA8LSBGaW5kU3BhdGlhbGx5VmFyaWFibGVGZWF0dXJlcyhraWRuZXksIGFzc2F5ID0gIlNDVCIsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhraWRuZXkpWzE6NTAwXSwKICAgIHNlbGVjdGlvbi5tZXRob2QgPSAibWFya3ZhcmlvZ3JhbSIpCnRvcC5mZWF0dXJlcyA8LSBoZWFkKFNwYXRpYWxseVZhcmlhYmxlRmVhdHVyZXMoa2lkbmV5LCBzZWxlY3Rpb24ubWV0aG9kID0gIm1hcmt2YXJpb2dyYW0iKSwgNikKU3BhdGlhbEZlYXR1cmVQbG90KGtpZG5leSwgZmVhdHVyZXMgPSB0b3AuZmVhdHVyZXMsIG5jb2wgPSAzLCBhbHBoYSA9IGMoMC4xLCAxKSkKYGBgCgpNb3JlIHR1dG9yaWFscyBvbiBkYXRhIGludGVncmF0aW9uLCBzdWJzZXR0aW5nIGFuZCBtdWx0aXBsZSBzbGljZSBkYXRhIGF2YWlsYWJsZSBhdCBodHRwczovL3NhdGlqYWxhYi5vcmcvc2V1cmF0L2FydGljbGVzL3NwYXRpYWxfdmlnbmV0dGUuaHRtbAoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=